package com.jt.www.admin.order_pc.service.impl;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.jt.www.admin.order_pc.service.ExtendService;
import com.jt.www.enums.extend.ExtendEnum;
import com.jt.www.enums.extend.ExtendMothedEnum;
import com.jt.www.model.remote.ins.EduExtendVO;
import com.jt.www.model.remote.ins.InsExtendVO;
import com.jt.www.model.reps.GenericListResponse;
import com.jt.www.model.vo.EduExtendQo;
import com.jt.www.remote.ins.InsClient;
import com.jt.www.util.DateUtils;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ProjectName: edu-service
 * @Package: com.jt.www.service.application
 * @ClassName: ExtendServiceImpl
 * @Author: lq
 * @Description: ${description}
 * @Date: 2020-05-07 18:49
 * @Version: 1.0
 */
@Service
public class ExtendServiceImpl implements ExtendService {

    public static final Logger log = LoggerFactory.getLogger(ExtendServiceImpl.class);
    private static final int DEFUALT_QUERY_NUM = 1000;
    @Autowired
    private InsClient insClient;

    /**
     * 添加扩展信息
     *
     * @param list        结果集
     * @param channelType 渠道类型编号
     * @param isDown      是否是导出
     */
    @Override
    public <T extends InsExtendVO> void setExtends(List<T> list, String channelType, boolean isDown, boolean isManager) {
        //得到需要查询的扩展字段集合
        Map<ExtendMothedEnum, List<String>> extendMap = ExtendEnum.getExtendMap(channelType, isDown, isManager);
        //得到所有投保单与保单ip对应
        Map<Long, Long> policyIdMap = list.stream().collect(Collectors.toMap(InsExtendVO::getPolicyId, InsExtendVO::getId, (key1, key2) -> key2));

        //分批特定的投保单数执行添加扩展字段
        Lists.partition(list, DEFUALT_QUERY_NUM).stream().parallel().forEach(insExtends -> {
            List<Long> appIds = Lists.newArrayList(Iterables.transform(insExtends, input -> input.getId()));
            //获得定单号对应的查询扩展信息集合的map
            Map<Long, List<EduExtendVO>> extendListMap = Maps.newConcurrentMap();
            extendMap.entrySet().stream().parallel().forEach(entry -> getExtends(entry, appIds, policyIdMap, channelType, extendListMap));
            log.debug("添加扩展-parallel结束时间{}", DateUtils.format(new Date(), DateUtils.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS_SSS));

            //添加扩展信息
            insExtends.stream().forEach(insExtendVO -> {
                List<EduExtendVO> extendList = extendListMap.get(insExtendVO.getId());
                if (CollectionUtils.isNotEmpty(extendList)) {
                    //为该投保单赋值
                    extendList.stream().forEach(eduExtend -> ExtendEnum.getExtendEnum(channelType, eduExtend.getFieldCode()).setValue(insExtendVO, eduExtend.getFieldValues()));
                }
            });
        });
    }

    /**
     * 查询扩展信息
     */
    private void getExtends(Map.Entry<ExtendMothedEnum, List<String>> entry, List<Long> appIds,
                            Map<Long, Long> policyIdMap, String channelType, Map<Long, List<EduExtendVO>> extendListMap) {
        //查询条件
        EduExtendQo eduExtendQo = new EduExtendQo();
        //添加准备查询的id
        if (entry.getKey().isAppId()) {
            eduExtendQo.setAppIds(appIds);
        }
        if (entry.getKey().isPolicyId()) {
            eduExtendQo.setPolicyIds(policyIdMap.keySet());
        }
        //添加查询的扩展字段code
        eduExtendQo.setFieldCodes(entry.getValue());
        ResponseEntity<GenericListResponse<EduExtendVO>> rets = entry.getKey().select(insClient, JSON.toJSONString(eduExtendQo));
        //投保中心返回的结果集
        List<EduExtendVO> list;
        //判断 结果集是不是空的
        if (null == rets || null == rets.getBody() || CollectionUtils.isEmpty(list = rets.getBody().getList())) {
            return;
        }
        //给返回结果赋值
        for (EduExtendVO eduExtendVO : list) {
            if (null == eduExtendVO.getAppId() || 0 == eduExtendVO.getAppId()) {
                Long appId = policyIdMap.get(eduExtendVO.getPolicyId());
                if (appId == null) {
                    continue;
                }
                eduExtendVO.setAppId(appId);
            }
            List<EduExtendVO> eduExtendVOS = extendListMap.containsKey(eduExtendVO.getAppId()) ? extendListMap.get(eduExtendVO.getAppId()) : Lists.newCopyOnWriteArrayList();

            //是否需要添加新的扩展字段
            boolean isAddExtend = true;
            //判断该投保单之前是不是有插入过该扩展字段的值
            for (EduExtendVO appExtendVO : eduExtendVOS) {
                //如果相同判断是否 需要相加值
                if (appExtendVO.getFieldCode().equals(eduExtendVO.getFieldCode())
                        //判断是否为数值类型且需要值 累加
                        && ExtendEnum.getExtendEnum(channelType, eduExtendVO.getFieldCode()).getIsAdd()) {
                    BigDecimal eduExtendValue = new BigDecimal(eduExtendVO.getFieldValues());
                    BigDecimal appExtendValue = new BigDecimal(appExtendVO.getFieldValues());
                    //将计算后的该扩展字段值 累加放回该扩展字段中
                    appExtendVO.setFieldValues(eduExtendValue.add(appExtendValue).toString());
                    //修改原扩展字段值不需要新添加扩展字段
                    isAddExtend = false;
                    break;
                }
            }
            //是否需要添加新的扩展字段
            if (isAddExtend) {
                eduExtendVOS.add(eduExtendVO);
            }
            //放到该投保单对应的扩展字段集合中
            extendListMap.put(eduExtendVO.getAppId(), eduExtendVOS);
        }
    }
}
